package com.fgsort;

import java.util.ArrayList;
import java.util.List;
import java.io.IOException;

import org.w3c.dom.Element;
import org.xml.sax.SAXException;

import com.utils.Exclude;

public class SymbolCompare {
	
	///check plc vs ruplan only (no plc source file)
	public ArrayList<List<String>> processTable(List<String> lstSymbols)	{
		
		final int nColMax = 8;

		///convert list to 2d list (row creation)
		ArrayList<List<String>> lstTable = new ArrayList<List<String>>();
		ArrayList<List<String>> lstTableResult = new ArrayList<List<String>>();

		int k=0;

		for (int i = 0; i < lstSymbols.size()/nColMax; i++)	{
			List<String> lstTableField = new ArrayList<String>();
			for (int j = 0; j < nColMax; j++)	{
				lstTableField.add(lstSymbols.get(k));
				k++;	
			}
			lstTable.add(lstTableField);
		}
		
		///iterate through each row and do checks
		for(List<String> lstRow : lstTable)	{

			StringBuilder sFaultResult = new StringBuilder();;
			String sep = new String(",");

			ArrayList<String> lstFault = new ArrayList<String>();

			///checks symbol fault and return with added
			if (isFaultSymbol(lstRow))	
				lstFault.add("Symbol");

			///checks comment fault and return with added
			if (isFaultComment(lstRow))	
				lstFault.add("Comment");

			if (lstFault.size()>0)	{
				short i = 0;
				for (String each : lstFault) {
					if (i==0)	
						sFaultResult.append(each);
					else
						sFaultResult.append(sep).append(each);
					i++;
				}
				lstRow.add(sFaultResult.toString());
			}
			lstTableResult.add(lstRow);
		}
		return lstTableResult;
	}
	
	///overloaded - include plc source file to check
	public ArrayList<List<String>> processTable(List<String> lstSymbols, List<String> lstPlcSrc, Element eXmlExcl) throws IOException, SAXException	{
		
		final int nColMax = 8;

		///convert list to 2d list (row creation)
		ArrayList<List<String>> lstTable = new ArrayList<List<String>>();
		ArrayList<List<String>> lstTableResult = new ArrayList<List<String>>();
		List<String> lstPlcSrcNWS = new ArrayList<String>();

		int k=0;

		for (int i = 0; i < lstSymbols.size()/nColMax; i++)	{
			List<String> lstTableField = new ArrayList<String>();
			for (int j = 0; j < nColMax; j++)	{
				lstTableField.add(lstSymbols.get(k));
				k++;	
			}
			lstTable.add(lstTableField);
		}
		
		///remove all whitespace from plc src
		for(String sPlcSrcLine : lstPlcSrc)
			lstPlcSrcNWS.add(sPlcSrcLine.replaceAll("\\s+", ""));

		///iterate through each row and do checks
		for(List<String> lstRow : lstTable)	{
			
			StringBuilder sFaultResult = new StringBuilder();
			String sep = new String(",");

			List<String> lstFault = new ArrayList<String>();
			List<String> lstRowResult = new ArrayList<String>();

			///checks symbol fault and return with added
			if (isFaultSymbol(lstRow))	
				lstFault.add("Symbol");

			///checks comment fault and return with added
			if (isFaultComment(lstRow))	
				lstFault.add("Comment");

			///checks if not used in plc and return with added
			if (isUsedInPlc(lstRow, lstPlcSrcNWS, eXmlExcl))	
				lstFault.add("Not used in plc");

			///checks if spare is used
			if(isSpareUsedInPlc(lstRow, lstPlcSrcNWS, eXmlExcl))
				lstFault.add("Spare used in plc");
			
//			if (lstFault.size() == 0)	{
//
//
//			}
			
			if (lstFault.size()>0)	{
				short i = 0;
				for (String each : lstFault) {
					if (i==0)	
						sFaultResult.append(each);
					else
						sFaultResult.append(sep).append(each);
					i++;
					
					if (lstFault.size() == i) {
						lstRowResult.addAll(lstRow);
						lstRowResult.add(sFaultResult.toString());
					}
				}
			}
			else	{
				lstRowResult.addAll(lstRow);
			}
			
			lstTableResult.add(lstRowResult);
		}
		return lstTableResult;
	}

	
	///symbol fault
	private boolean isFaultSymbol(List<String> lstRow) {
		
	if (!lstRow.get(0).equals(lstRow.get(4)))
		return true;
	else 
		return false;
	}

	///comment fault
	private boolean isFaultComment(List<String> lstRow) {
		
	if (!lstRow.get(3).equalsIgnoreCase(lstRow.get(7)) && !lstRow.get(3).equalsIgnoreCase("Reserve") && !lstRow.get(7).equals(""))
		return true;
	else 
		return false;
	}
	
	///input/output is in ruplan but is not used in plc
	private boolean isUsedInPlc(List<String> lstSymbolRow, List<String> lstPlcSrcNWS, Element eXmlExcl) throws SAXException	{

		String sAddressNWS;

		if (Exclude.isExNotUsedInPlc(eXmlExcl, lstSymbolRow))	{
			return false;
		}
		
		
		if (lstSymbolRow.get(1).equals(""))
			sAddressNWS = lstSymbolRow.get(5).replaceAll("\\s+", "");
		else
			sAddressNWS = lstSymbolRow.get(1).replaceAll("\\s+", "");

		for(String str : lstPlcSrcNWS)	{
			if (str.contains(sAddressNWS)) {		
				return false;
			}
		}
		return true;
	}

	///spare/reserve is used in plc
	private boolean isSpareUsedInPlc(List<String> lstSymbolRow, List<String> lstPlcSrcNWS, Element eXmlExcl) throws SAXException{
		
		String sAddressNWS;
		
		if (!lstSymbolRow.get(1).equals(""))
			sAddressNWS = lstSymbolRow.get(1).replaceAll("\\s+", "");
		else
			return false;

		///check if 'io spare' matches 'symbol spare'
		if (lstSymbolRow.get(0).contains(sAddressNWS) || lstSymbolRow.get(0).contains("999RES"))	{
			for(String str : lstPlcSrcNWS)	{
				if (str.contains(sAddressNWS)) {		
					return true;
				}
			}
		}
		return false;
	}
	
	private boolean isFound(String source, String key)	{
		return source.indexOf(key) > -1;
	}

}